package com.bdqn.petmalldemo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bdqn.petmalldemo.bo.PasswordQuestionBo;
import com.bdqn.petmalldemo.bo.QuestionRecoverBo;
import com.bdqn.petmalldemo.bo.UserLoginBo;
import com.bdqn.petmalldemo.bo.UserRegisterBo;
import com.bdqn.petmalldemo.common.KetaiException;
import com.bdqn.petmalldemo.common.ResultCodeEnum;
import com.bdqn.petmalldemo.common.SystemConstants;
import com.bdqn.petmalldemo.common.TokenCache;
import com.bdqn.petmalldemo.entity.User;
import com.bdqn.petmalldemo.mapper.UserMapper;
import com.bdqn.petmalldemo.service.UserService;
import com.bdqn.petmalldemo.utils.MD5;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Lenovo
 * @since 2020-02-10
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public void userRegister(UserRegisterBo userRegisterBo) {
        //1.检查用户名 邮箱 手机号是否重复
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
        //判断用户名
        queryWrapper.eq("username",userRegisterBo.getUsername());
            User user = baseMapper.selectOne(queryWrapper);
            //log.info(user.getUsername());
            //判断该用户是否存在,如果存在，则证明用户名或邮箱或手机号已经存在
        //TODO:2020/2/13 用户名手机号邮箱重复提示
        if(user!=null) {
            //证明访问用户名或邮箱或手机号已被使用,通过抛出异常的方式给到前台提示信息
            //抛出自定义异常
            throw new KetaiException(ResultCodeEnum.USERNAME_IS_EXIST);
        }
            //判断邮箱是否存在
            queryWrapper= new QueryWrapper<User>().eq("email",userRegisterBo.getEmail());
            user=baseMapper.selectOne(queryWrapper);
            if (user !=null){
                //证明根据邮箱查询用户是存在,邮箱重复
                throw new KetaiException(ResultCodeEnum.EMAIL_IS_EXIST);
            }
            //判断手机号是否重复
            queryWrapper=new QueryWrapper<User>().eq("phone",userRegisterBo.getPhone());
            user=baseMapper.selectOne(queryWrapper);
            if (user!=null){
                throw  new KetaiException(ResultCodeEnum.PHONE_IS_EXIST);
            }
            //对用户密码进行MD5加密
            String md5Password = MD5.encode(userRegisterBo.getPassword() + SystemConstants.MD5_SLAT);
            userRegisterBo.setPassword(md5Password);
            //完成注册
            User userRegister=new User();
            //调用工具类完成属性的复制
            BeanUtils.copyProperties(userRegisterBo,userRegister);
            //给定默认的角色
            userRegister.setRole(SystemConstants.USER_ROLE.GENERAL);
            this.save(userRegister);

    }

    @Override
    public User userLogin(UserLoginBo userLoginBo,String ipAddress) {
        QueryWrapper<User> wrapper = new QueryWrapper<User>();
        wrapper.eq("username", userLoginBo.getUsername())
                .eq("password",MD5.encode(userLoginBo.getPassword()+SystemConstants.MD5_SLAT))
                .eq("role",userLoginBo.getRole());
        User user = baseMapper.selectOne(wrapper);
        if (user ==null){
            throw  new KetaiException(ResultCodeEnum.USERNAME_OR_PASSWORD_ERROR);
        }
        //1.判断该用户是否禁用
        if(user.getStatus().equals(SystemConstants.USER_STATUS.DISABLED)){
            throw  new KetaiException(ResultCodeEnum.USER_DIEABLED);
        }
        //登录成功后更新最后登录时间和登录ip
        user.setLoginTime(LocalDateTime.now(ZoneId.systemDefault()));
        user.setLoginIp(ipAddress);
        //执行更新，完成登录ip和最后登录时间的更新
        baseMapper.updateById(user);
        user.setPassword(null);
        return  user;
    }

    @Override
    public void questionRecover(QuestionRecoverBo questionRecoverBo) {
        //先根据token从TokenCache中取出当前登录用户信息
        String jsonUser = TokenCache.get(questionRecoverBo.getToken());
        User user = JSONObject.parseObject(jsonUser, User.class);
        //根据用户Id查询用户信息
        User userById = this.getById(user.getId());
        //判断当前用户的历史安全问题是否为空
        boolean oldQuestionIsExist=StringUtils.isEmpty(userById.getQuestion())&&StringUtils.isEmpty(userById.getAnswer());
        //前端传递过来的历史安全问题是否为空
        boolean oldQuestionIsNull=StringUtils.isEmpty(questionRecoverBo.getOldQuestion())&&StringUtils.isEmpty(questionRecoverBo.getOldAnswer());
        //执行安全问题的设置,通过判断历史安全问题及命案是否为空来区别是新增还是修改
        if (oldQuestionIsNull&&oldQuestionIsExist) {
            //将前台传递过来
            userById.setQuestion(questionRecoverBo.getNewQuestion());
            userById.setAnswer(questionRecoverBo.getNewAnswer());
            //当历史安全问题及答案都为空的时候,则直接修改安全问题和答案
            this.updateById(userById);
        }else {
            //如果历史安全问题存在，需要做准确性的校验
            if (userById.getQuestion().equals(questionRecoverBo.getOldQuestion())
                    &&userById.getAnswer().equals(questionRecoverBo.getOldAnswer())) {
                //将前台传递过来新的安全问题赋值user对象
                userById.setQuestion(questionRecoverBo.getNewQuestion());
                userById.setAnswer(questionRecoverBo.getNewAnswer());
                this.updateById(userById);
            }else{
                throw  new KetaiException(ResultCodeEnum.QUESTION_ANSWER_ERROR);
            }
        }
    }

    @Override
    public String getPasswordQuestion(PasswordQuestionBo passwordQuestionBo) {
        //根据用户名和邮箱来获取安全问题
        QueryWrapper<User> userqueryWrapper = new QueryWrapper<User>();
        userqueryWrapper.eq("username",passwordQuestionBo.getUsername())
                .eq("email",passwordQuestionBo.getEmail());
        User user = baseMapper.selectOne(userqueryWrapper);
        //判断该用户是否为空
        if (user==null) {
            throw new  KetaiException(ResultCodeEnum.USER_NOT_EXIST);
        }
        return user.getQuestion();
    }

    @Override
    public String passwordRecover(PasswordQuestionBo passwordQuestionBo) {
        //先根据用户名和邮箱查询用户名
        QueryWrapper<User> userqueryWrapper = new QueryWrapper<User>();
        userqueryWrapper.eq("username",passwordQuestionBo.getUsername())
                .eq("email",passwordQuestionBo.getEmail());
        User user = baseMapper.selectOne(userqueryWrapper);
        //将前台传递过来的安全问题和答案进行比对
        if (user==null) {
            throw  new KetaiException(ResultCodeEnum.USER_NOT_EXIST);
        }
        //安全问题校验不存在
        if (!(user.getQuestion().equals(passwordQuestionBo.getQuestion())
                && user.getAnswer().equals(passwordQuestionBo.getAnswer()))){
            throw new KetaiException(ResultCodeEnum.QUESTION_ANSWER_ERROR);
        }
        //生成随机密码，更新到数据库
        String randomPassword = Integer.toString(RandomUtils.nextInt(100000,999999));
        String md5Password = MD5.encode(randomPassword+SystemConstants.MD5_SLAT);
        user.setPassword(md5Password);
        baseMapper.updateById(user);
        return randomPassword;
    }

    @Override
    public Map<String,Object> searchMember(Integer status,String keyword) {
        IPage<User> page=new Page<>();
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("role",SystemConstants.USER_ROLE.GENERAL)
                .eq(!StringUtils.isEmpty(status)&&
                        (status.equals(SystemConstants.USER_STATUS.DISABLED)||
                        status.equals(SystemConstants.USER_STATUS.ENABLE))
                         ,"status",status)
                .like(!StringUtils.isEmpty(keyword),"username",keyword);
         baseMapper.selectPage(page,userQueryWrapper);
         Map<String, Object> map = new HashMap<>(16);
        //完成数据的处理
        map.put("list",page.getRecords());
        map.put("pages",page.getPages());
        map.put("pageNum",page.getCurrent());
        map.put("total",page.getTotal());
        return map;
    }

    @Override
    public void updateStatus(String userId, Integer status) {
        //先查询当前用户是否存在
        User user= this.getById(userId);
        if (user==null) {
            //用户不存在
            throw  new KetaiException(ResultCodeEnum.USER_NOT_EXIST);
        }
        user.setStatus(status);
        baseMapper.updateById(user);
    }

    @Override
    public boolean checkActive(String userId) {
        //先根据Id查询用户信息
        User user = baseMapper.selectById(userId);
        if (user==null) {
            //用户不存在
            throw  new KetaiException(ResultCodeEnum.USER_NOT_EXIST);
        }
        return SystemConstants.USER_STATUS.ENABLE.equals(user.getStatus());

    }
}
